<template>
  <el-dialog :append-to-body="true" :show-close="false" :close-on-click-modal="false" v-bind="$attrs" title="报表预览" height="100%" top="0vh" v-on="$listeners" @opened="onOpen" @close="onClose">
    <div :style="{'text-align': 'right'}" class="action-bar">
      <span class="bar-btn" @click="runCode">
        <i class="el-icon-refresh" />
        刷新
      </span>
      <span v-permission="['SYS_ADMIN']" class="bar-btn" @click="exportFile">
        <i class="el-icon-download" />
        导出vue文件
      </span>
      <span v-permission="['SYS_ADMIN','COMMON_ADMIN','FORM_SET_ALL','FORM_SET_CHANGE','FORM_SET_CREATE']" id="preview-copy-btn" ref="copyBtn" class="bar-btn copy-btn">
        <i class="el-icon-document-copy" />
        复制代码
      </span>
      <span class="bar-btn delete-btn" @click="$emit('update:visible', false)">
        <i class="el-icon-circle-close" />
        关闭
      </span>
    </div>
    <DynamicLoad
      v-if="isIframeLoaded"
      ref="dynamicLoad"
      :comp-id="compId"
      :html-code="htmlCode"
      :js-code="jsCode" />
  </el-dialog>
</template>
<script>
import ClipboardJS from 'clipboard'
import { saveAs } from 'file-saver'
import beautifier from 'js-beautify'
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/views/formgenerator/components/generator/html'
import { makeUpJs } from '@/views/formgenerator/components/generator/js'
import { makeUpCss } from '@/views/formgenerator/components/generator/css'
import { exportDefault, beautifierConf } from '@/utils/index'
import DynamicLoad from '@/components/DynamicLoader/index'

export default {
  components: { DynamicLoad },
  props: {
    formData: {
      type: Object,
      required: false,
      default: null
    },
    generateConf: {
      type: Object,
      required: false,
      default: null
    }
  },
  data() {
    return {
      isIframeLoaded: false,
      scripts: [],
      links: [],
      htmlCode: '',
      jsCode: '',
      compId: +new Date() + ''
    }
  },
  watch: {},
  created() {},
  mounted() {
    window.addEventListener('keydown', this.preventDefaultSave)
    const clipboard = new ClipboardJS('#preview-copy-btn', {
      text: trigger => {
        const codeStr = this.generateCode()
        this.$notify({
          title: '成功',
          message: '代码已复制到剪切板，可粘贴。',
          type: 'success'
        })
        return codeStr
      }
    })
    clipboard.on('error', e => {
      this.$message.error('代码复制失败')
    })
  },
  beforeDestroy() {
    window.removeEventListener('keydown', this.preventDefaultSave)
  },
  methods: {
    preventDefaultSave(e) {
      if (e.key === 's' && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
      }
    },
    onOpen() {
      setTimeout(() => {
        this.runCode()
      })
    },
    onClose() {},
    runCode() {
      try {
        this.isIframeLoaded = false
        const { type } = this.generateConf
        const htmlCode = makeUpHtml(this.formData, type)
        this.htmlCode = beautifier.html(htmlCode, beautifierConf.html)
        const jsCode = makeUpJs(this.formData, type)
        this.jsCode = beautifier.js(jsCode, beautifierConf.js).replace(exportDefault, '')
        const cssCode = makeUpCss(this.formData)
        this.cssCode = beautifier.css(cssCode, beautifierConf.html)
        this.isIframeLoaded = true
      } catch (err) {
        this.$message.error(`js error:${err}`)
        console.error(err)
      }
    },
    generateCode() {
      const html = vueTemplate(this.htmlCode)
      const script = vueScript(this.jsCode)
      const css = cssStyle(this.cssCode)
      return beautifier.html(html + script + css, beautifierConf.html)
    },
    exportFile() {
      this.$prompt('文件名:', '导出文件', {
        inputValue: `${+new Date()}.vue`,
        closeOnClickModal: false,
        inputPlaceholder: '请输入文件名'
      }).then(({ value }) => {
        if (!value) value = `${+new Date()}.vue`
        const codeStr = this.generateCode()
        const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' })
        saveAs(blob, value)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/mixin.scss';
@include action-bar;
::v-deep .el-dialog__header {
  display: none;
}
::v-deep .el-dialog__body {
  padding: 10px 10px;
}
</style>
